package ihm_clarifiee.application;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;




import javax.sound.midi.SysexMessage;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane.RestoreAction;


import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import ihm_clarifiee.Control.CBacklog;
import ihm_clarifiee.Control.CProjet;
import ihm_clarifiee.Control.CUsine;
import ihm_clarifiee.sauvegarde.Originator;
import ihm_clarifiee.sauvegarde.Project_State;
import ihm_clarifiee.sauvegarde.CareTaker;
/**
 * @(#) Projet.java
 */
 public class Projet extends SaveAndRestore<Project_State,Projet>
{
	/**
	 * 
	 */
	protected Backlog m_backlog;
	protected ArrayList<Release> m_listeRelease;
	protected ArrayList<Equipe> m_listeEquipe;
	

	
	protected String m_titre;
	protected String m_description;
	protected String m_objectifs;
	protected Date m_dateDebut;
	protected Integer m_dureeSprint;
	protected Release m_releaseActive;
    protected Usine m_usine;
    
    private CBacklog cBacklog;

//    XML
    private static org.jdom.Document document;
	private static Element racine;
    
	public Projet( Usine u,String titre, String description, String objectifs, Date dateDebut, Integer dureeSprint){
		System.out.println("***Création d'un Projet***");
//		this.setListeRelease(new ArrayList<Release>());
		m_listeRelease = new ArrayList<Release>();
        this.m_usine = u;
		this.m_titre = titre;
		this.m_description = description;
		this.m_objectifs = objectifs;
		this.m_dateDebut = dateDebut;
		this.m_dureeSprint = dureeSprint;	
//		this.m_backlog = m_usine.newBacklog(this);

//        creerRelease("test", "objectifs", dateDebut, new Date((dateDebut.getYear()+1), dateDebut.getMonth(),dateDebut.getDay()));
//        m_releaseActive = m_listeRelease.get(0);
        
//      Sauvegarde
        this.careTaker = new CareTaker<Project_State>();
        this.originator = new Originator<Project_State>(null);
	}

	
	public Usine getUsine(){
		return this.m_usine;
	}
	
	/**
	 * 
	 * @param t : Titre
	 */
	public void setTitre( String t )
	{
		this.m_titre = t;
	}
	/**
	 * 
	 * @return
	 */
	public String getTitre( )
	{
		return this.m_titre;
	}
	
	/**
	 * 
	 * @param d
	 */
	public void setDescription( String d )
	{
		this.m_description = d;
	}
	
	/**
	 * 
	 * @return
	 */
	public String getDescription( )
	{
		return this.m_description;
	}
	
	/**
	 * 
	 * @param o
	 */
	public void setObjectifs( String objectifs )
	{
		this.m_objectifs = objectifs;
	}
	/**
	 * 
	 * @return
	 */
	public String getObjectifs( )
	{
		return this.m_objectifs;
	}
	
	/**
	 * 
	 * @param d
	 */
	public void setDateDebut( Date d )
	{
		this.m_dateDebut = d;
	}
	
	/**
	 * 
	 * @return
	 */
	public Date getDateDebut( )
	{
		return this.m_dateDebut;
	}

	/**
	 * 
	 * @param dureeSprint
	 */
	public void setDureeSprint(Integer dureeSprint) {
		this.m_dureeSprint = dureeSprint;
	}
	/**
	 * 
	 * @return
	 */
	public Integer getDureeSprint() {
		return m_dureeSprint;
	}
	
	/*Gestion des equipes*/
	
	public void creerEquipe( String nomEquipe, Utilisateur scrumMaster, String description  )
	{

		Equipe r = m_usine.newEquipe(m_usine, this, nomEquipe, scrumMaster, description) ;
		getListeEquipe().add(r);             
	}
	
	public void supprimerEquipe( Equipe eq )
	{
		getListeRelease().remove(eq);
	}
	
	/**
	 * @param m_listeEquipe the m_listeEquipe to set
	 */
	public void setListeEquipe(ArrayList<Equipe> lr) {
		this.m_listeEquipe.addAll(lr);// = m_listeRelease;
	}


	/**
	 * @return the m_listeEquipe
	 */
	public ArrayList<Equipe> getListeEquipe() {
		return m_listeEquipe;
	}
	
	

	/*----------------------*/
	

	 /* gestion des releases : */
	
	public void creerRelease( String nom, String objectif, Date dateD, Date dateF )
	{
		Release r = m_usine.newRelease(m_usine,this, nom, objectif, dateD, dateF);
		getListeRelease().add(r);             
	}
	
	public void supprimerRelease( Release rel )
	{
		getListeRelease().remove(rel);
	}
	
	/**
	 * @param m_listeRelease the m_listeRelease to set
	 */
	public void setListeRelease(ArrayList<Release> lr) {
		this.m_listeRelease.addAll(lr);// = m_listeRelease;
	}


	/**
	 * @return the m_listeRelease
	 */
	public ArrayList<Release> getListeRelease() {
		return m_listeRelease;
	}
	
	/**
	 * 
	 * @param r
	 */
	public void setReleaseActive(Release r){
		this.m_releaseActive = r;
	}
	
	/**
	 * 
	 * @return
	 */
	public Release getReleaseActive(){
		return this.m_releaseActive;
	}

	public Backlog getBacklog(){
		return this.m_backlog;
	}

	public void setBacklog(Backlog b){
		this.m_backlog = b;
	}
	/**
	 * Etat courant du projet
	 * @return un "Project_State"
	 */
	public Project_State getState(){
		return new Project_State(m_titre, m_description, m_objectifs, m_dateDebut, m_releaseActive);
	}


	@Override
	public void save() {
//		Creation d'un memento et ajout au careTaker
		originator.setState(new Project_State(this)); //faire un clone ??
		careTaker.addMemento(originator.saveToMemento());
		Iterator<Release> it = getListeRelease().iterator();
		while(it.hasNext()){
			it.next().save();
		}
		getBacklog().save();
	}


	@Override
	public void restore() {
		// TODO Auto-generated method stub	
	}
	
	@SuppressWarnings("deprecation")
	@Override
	public void saveToXML(String nomRepertoire) {
//		tester si le state != null
		Projet p_saved = careTaker.getMemento(0).getSaveState().getProjet();

//		Creation du Document XML avec une racine
        racine = new Element("Produit");
        racine.setAttribute(new Attribute("titre",p_saved.getTitre()));
        document = new Document(racine);
        
		Element personnes = new Element("titre");
		personnes.setText(p_saved.getTitre());
		racine.addContent(personnes);
		
		Element description = new Element("description");
		description.setText(p_saved.getDescription());
		racine.addContent(description);
		
		Element objectifs = new Element("objectifs");
		objectifs.setText(p_saved.getObjectifs());
		racine.addContent(objectifs);
		

//		Backlog
		Element backlog = new Element("backlog");
		backlog.setText(p_saved.getBacklog().getNomFichier()); //nom unique(par projet)
		racine.addContent(backlog);
		p_saved.getBacklog().saveToXML(nomRepertoire);
		
		Element dateDebut = new Element("Date_de_debut");

		racine.addContent(dateDebut);
		
		Date db = p_saved.getDateDebut();
//		jour
		Element jour  = new Element("jour");
		jour.setText(String.valueOf(db.getDate()));
		dateDebut.addContent(jour);
//		mois
		Element mois  = new Element("mois");
		mois.setText(String.valueOf(db.getMonth()+1)); //janvier = 00
		dateDebut.addContent(mois);
//		annee
		Element annee = new Element("annee");
		annee.setText(String.valueOf(db.getYear()));
		dateDebut.addContent(annee);

		Element dureeSprint = new Element("Duree_des_sprints");
		dureeSprint.setText(p_saved.getDureeSprint().toString());
		racine.addContent(dureeSprint);
		
		Element releaseActive = new Element("Release_Active");

		if(p_saved.getReleaseActive()!= null)
			releaseActive.setText(p_saved.getReleaseActive().getNom()); //juste le nom est stocke, le reste des info sera ds un fichier e part

		racine.addContent(releaseActive);
		
//		Ajout des noms des Releases du projet
		Iterator<Release> it = p_saved.getListeRelease().iterator();
		Element releases = new Element("Releases");
		releases.setAttribute(new Attribute("taille", String.valueOf(p_saved.getListeRelease().size())));
		
		racine.addContent(releases);
		while(it.hasNext()){
			Release r = it.next();
			Element release = new Element("Release");
			release.setText(r.getNom());
			releases.addContent(release);
//			On la sauvegarde dans son fichier
			r.saveToXML(nomRepertoire);
		}
		System.out.println("Enregistrement XML");
//		Enregistre dans un fichier XML
		enregistre(nomRepertoire+"/"+p_saved.getNomFichier()+".xml",document);
	}	

	/**
	 * 
	 * @param nomFichier
	 * @return
	 */
	public static CProjet restoreFromXML(String nomFichier,String nomRepertoire) {
		System.out.println("!!! Restauration Projet !!!");
		//On cree une instance de SAXBuilder
		SAXBuilder sxb = new SAXBuilder();
		try
		{
			//On cree un nouveau document JDOM avec en argument le fichier XML
	        //Le parsing est termine ;)
	        document = sxb.build(new File(nomFichier));
	     }
	     catch(Exception e){}
	     
	     //On initialise un nouvel element racine avec l'element racine du document.
	     racine = document.getRootElement();
	     
	    List<?> l = racine.getChildren();
	     	    
		String titre = (String) ((Element) l.get(0)).getText();
		String description = (String) ((Element) l.get(1)).getText();
		String objectifs = (String) ((Element) l.get(2)).getText();
		
//		Recuperation du nom du fichier Backlog
		String backlog = (String) ((Element) l.get(3)).getText();		

//		Recuperation de la Date
		List<?> listeDate = ((Element) l.get(4)).getChildren();
		int jour  = Integer.valueOf((String) ((Element) listeDate.get(0)).getText());
		int mois  = Integer.valueOf((String) ((Element) listeDate.get(1)).getText());
		int annee = Integer.valueOf((String) ((Element) listeDate.get(2)).getText());

		@SuppressWarnings("deprecation")
		Date dateDebut = new Date(annee, mois-1, jour); 
		
//		Recuperation de la duree des sprint
		Integer dureeSprint = Integer.parseInt((String) ((Element) l.get(5)).getText());		

//		La Release Active
		
//	    Construction d'un nouveau projet
		CUsine u = new CUsine();
	    CProjet p_restored = new CProjet(u, titre, description, objectifs, dateDebut, dureeSprint);
	    
//	    Restauration de la liste des releases
		ArrayList<Release> listeRelease = new ArrayList<Release>();
		Element liste = (Element) l.get(7);
		List<?> listeReleases = liste.getChildren();
		
		int taille_liste = Integer.valueOf(liste.getAttributeValue("taille"));
		for(int i=0;i<taille_liste;i++){		
			Release r_restored = Release.restoreFromXML(((Element) listeReleases.get(i)).getText()+".xml", nomRepertoire, u, p_restored);
			listeRelease.add(r_restored); 
			//On recupere les releases 
			//dans leur fichier grace a leur nom
		}
		
		CBacklog cb = Backlog.restoreFromXML(backlog, nomRepertoire, p_restored);
//		cBacklog = Backlog.restoreFromXML(backlog, nomRepertoire, p_restored);
//		Set backlog
		p_restored.setCBacklog(cb);
		p_restored.setBacklog(cb);
		
//		Set de la liste des releases 
	    p_restored.setListeRelease(listeRelease);
	    String nom_releaseActive = (String) ((Element) l.get(6)).getText();
//	    ---------et de la release Active
	    if(nom_releaseActive!=""){
		    Release releaseActive = Release.restoreFromXML(nom_releaseActive+".xml", nomRepertoire, u, p_restored);
		    p_restored.setReleaseActive(releaseActive);
	    }
	
	    return p_restored;
	}
	protected void setCBacklog(CBacklog cb){
		cBacklog = cb;
	}
	public CBacklog getCBacklog(){
		return this.cBacklog;
	}
			
	/**
	 * 
	 */
	public String toString(){
		return "\nTitre : "+this.m_titre+
		"\nDescription : "+this.m_description+
		"\nObjectifs : "+this.m_objectifs+
		"\nDate de debut : "+this.m_dateDebut+
		"\nDuree des sprints : "+this.m_dureeSprint+"\n";
	}


	@Override
	public String getNomFichier() {
		return this.m_titre;
	}

	/**
	 * @return the caretaker
	 */
	public CareTaker<Project_State> getCaretaker() {
		return careTaker;
	}
	
}
